package com.ddm.utils;

import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.ddm.result.Result;
import com.google.gson.Gson;
import com.aliyun.credentials.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 阿里云短信发送工具类，结合Redis实现验证码验证功能
 */
@Component
public class SendMUtil {
    // 阿里云配置
    @Value("${cx.ali.accessKeyId}")
    private String accessKeyId;
    @Value("${cx.ali.accessKeySecret}")
    private String accessKeySecret;

    // Redis模板，用于操作Redis
    private final StringRedisTemplate stringRedisTemplate;

    // 验证码过期时间(分钟)
    private static final int CODE_EXPIRE_MINUTES = 5;

    // 注入Redis模板
    public SendMUtil(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 创建阿里云短信客户端
     */
    public com.aliyun.dysmsapi20170525.Client createClient() throws Exception {
        // 使用类中注入的AK/SK
        return createClient(accessKeyId, accessKeySecret);
    }

    /**
     * 创建阿里云短信客户端
     */
    public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.credentials.models.Config credentialConfig = new com.aliyun.credentials.models.Config();
        credentialConfig.setType("access_key");
        credentialConfig.setAccessKeyId(accessKeyId);
        credentialConfig.setAccessKeySecret(accessKeySecret);

        Client credential = new Client(credentialConfig);
        Config config = new Config().setCredential(credential);
        config.endpoint = "dysmsapi.aliyuncs.com";

        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    /**
     * 生成指定长度的随机验证码
     */
    public static String generateVerifyCode(int length) {
        if (length <= 0) {
            length = 6; // 默认6位验证码
        }

        StringBuilder code = new StringBuilder();
        Random random = new Random();

        for (int i = 0; i < length; i++) {
            code.append(random.nextInt(10)); // 生成0-9的数字
        }

        return code.toString();
    }
    /**
     * 发送预告过期通知短信
     *
     * @param signName      短信签名
     * @param templateCode  通知短信模板 CODE
     * @param phoneNumbers  接收短信的手机号，多个手机号用逗号分隔
     * @param userName      用户名
     * @param packageName   套餐名
     * @return 统一封装的 Result 结果，成功时 data 包含响应内容，失败时 msg 包含错误信息
     */
    public Result<String> sendAdPackageSms(String signName, String templateCode,
                                         String phoneNumbers, String userName, String packageName,String day) {
        try {
            // 1. 创建短信客户端
            com.aliyun.dysmsapi20170525.Client client = createClient();

            // 2. 构建模板参数JSON
            String templateParam = String.format("{\"name\":\"%s\",\"package\":\"%s\",\"day\":\"%s\"}",
                    userName, packageName,day);

            // 3. 构建发送请求
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setSignName(signName)
                    .setTemplateCode(templateCode)
                    .setPhoneNumbers(phoneNumbers)
                    .setTemplateParam(templateParam);

            // 4. 发送短信
            SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());

            // 5. 处理发送结果
            if ("OK".equals(response.getBody().getCode())) {
                return Result.success("通知短信发送成功");
            } else {
                return Result.error("通知短信发送失败：" + response.getBody().getMessage());
            }
        } catch (TeaException error) {
            return Result.error("通知短信发送失败：" + error.getMessage() + "，建议诊断：" + error.getData().get("Recommend"));
        } catch (Exception e) {
            TeaException teaException = new TeaException(e.getMessage(), e);
            return Result.error("通知短信发送异常：" + teaException.getMessage());
        }
    }
    /**
     * 发送过期通知短信
     *
     * @param signName      短信签名
     * @param templateCode  通知短信模板 CODE
     * @param phoneNumbers  接收短信的手机号，多个手机号用逗号分隔
     * @param userName      用户名
     * @param packageName   套餐名
     * @return 统一封装的 Result 结果，成功时 data 包含响应内容，失败时 msg 包含错误信息
     */
    public Result<String> sendPackageSms(String signName, String templateCode,
                                              String phoneNumbers, String userName, String packageName) {
        try {
            // 1. 创建短信客户端
            com.aliyun.dysmsapi20170525.Client client = createClient();

            // 2. 构建模板参数JSON
            String templateParam = String.format("{\"name\":\"%s\",\"package\":\"%s\"}",
                    userName, packageName);

            // 3. 构建发送请求
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setSignName(signName)
                    .setTemplateCode(templateCode)
                    .setPhoneNumbers(phoneNumbers)
                    .setTemplateParam(templateParam);

            // 4. 发送短信
            SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());

            // 5. 处理发送结果
            if ("OK".equals(response.getBody().getCode())) {
                return Result.success("通知短信发送成功");
            } else {
                return Result.error("通知短信发送失败：" + response.getBody().getMessage());
            }
        } catch (TeaException error) {
            return Result.error("通知短信发送失败：" + error.getMessage() + "，建议诊断：" + error.getData().get("Recommend"));
        } catch (Exception e) {
            TeaException teaException = new TeaException(e.getMessage(), e);
            return Result.error("通知短信发送异常：" + teaException.getMessage());
        }
    }
    /**
     * 发送验证码短信
     *
     *  client        已初始化的短信客户端
     * @param signName      短信签名
     * @param templateCode  短信模板 CODE
     * @param phoneNumbers  接收短信的手机号，多个手机号用逗号分隔
     *  templateParam 短信模板参数（JSON 格式字符串，如：{"code":"1234"}）
     * @return 统一封装的 Result 结果，成功时 data 包含响应内容，失败时 msg 包含错误信息
     */
    public Result<String> sendVerifyCode(String signName, String templateCode, String phoneNumbers) {
        try {
            // 1. 生成6位验证码
            String verifyCode = generateVerifyCode(6);

            // 2. 创建短信客户端
            com.aliyun.dysmsapi20170525.Client client = createClient();

            // 3. 构建模板参数
            String templateParam = String.format("{\"code\":\"%s\"}", verifyCode);

            // 4. 发送短信
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setSignName(signName)
                    .setTemplateCode(templateCode)
                    .setPhoneNumbers(phoneNumbers)
                    .setTemplateParam(templateParam);

            SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());

            // 5. 发送成功则将验证码存入Redis，设置过期时间
            if ("OK".equals(response.getBody().getCode())) {
                String redisKey = "verify:code:" + phoneNumbers;
                stringRedisTemplate.opsForValue().set(redisKey, verifyCode, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
                return Result.success("验证码发送成功"+verifyCode);
            } else {
                return Result.error("短信发送失败：" + response.getBody().getMessage());
            }
        } catch (TeaException error) {
            return Result.error("短信发送失败：" + error.getMessage() + "，建议诊断：" + error.getData().get("Recommend"));
        } catch (Exception e) {
            TeaException teaException = new TeaException(e.getMessage(), e);
            return Result.error("短信发送异常：" + teaException.getMessage());
        }
    }
    //redis测试
    public Result<String> test() {
        String redisKey = "test:1";
        try {
            // 1. 生成6位数字验证码
            String verifyCode = String.format("%06d", (int)(Math.random() * 1000000));

            // 2. 存储到Redis并设置过期时间
            stringRedisTemplate.opsForValue().set(redisKey, verifyCode, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);

            // 3. 获取存储的验证码
            String storedCode = stringRedisTemplate.opsForValue().get(redisKey);

            return Result.success("测试成功，验证码：" + storedCode);
        } catch (Exception e) {
            // 简单异常处理
            return Result.error("操作失败：" + e.getMessage());
        }
    }
    /**
     * 验证验证码是否正确
     */
    public Result<Boolean> verifyCode(String phoneNumber, String code) {
        if (phoneNumber == null || code == null) {
            return Result.error("手机号和验证码不能为空");
        }

        String redisKey = "verify:code:" + phoneNumber;
        String storedCode = stringRedisTemplate.opsForValue().get(redisKey);

        if (storedCode == null) {
            return Result.error("验证码已过期或未发送，请重新获取");
        }

        if (storedCode.equals(code)) {
            // 验证成功后删除验证码，防止重复使用
            stringRedisTemplate.delete(redisKey);
            return Result.success();
        } else {
            return Result.error("验证码不正确");
        }
    }
    /**
     * 手机号格式简单校验
     */
    public boolean isValidPhoneNumber(String phone) {
        // 简单校验中国大陆手机号格式
        return phone != null && phone.matches("^1[3-9]\\d{9}$");
    }

    /**
     * 邮箱格式简单校验
     */
    public boolean isValidEmail(String email) {
        if (email == null) {
            return false;
        }
        // 简单的邮箱格式正则
        String regex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$";
        return email.matches(regex);
    }

    // 测试方法
    public static void main(String[] args) throws Exception {
        // 注意：实际项目中不要这样创建实例，应通过Spring注入
        // StringRedisTemplate redisTemplate = ...; // 需要实际初始化RedisTemplate
        // SendMUtil smsUtil = new SendMUtil(redisTemplate);

        // 示例调用
        // Result<String> sendResult = smsUtil.sendVerifyCode(
        //         "广州文熵科技有限公司",
        //         "SMS_324555194",
        //         "16698509846"
        // );
        // System.out.println("发送结果：" + new Gson().toJson(sendResult));

        // // 验证验证码
        // Result<Boolean> verifyResult = smsUtil.verifyCode("16698509846", "123456");
        // System.out.println("验证结果：" + new Gson().toJson(verifyResult));
    }
}